package com.sam.spring.chapter3;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;

import org.junit.Assert;
import org.junit.Test;
import org.springframework.core.io.ByteArrayResource;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.FileSystemResource;
import org.springframework.core.io.InputStreamResource;
import org.springframework.core.io.Resource;

public class ResourceTest {
	@Test
	public void testByteArrayResource() {
		Resource resource = new ByteArrayResource("Hello Spring!".getBytes());
		if (resource.exists()) {
			dumpStream(resource);
		}
	}

	@Test
	public void testInputStreamResource() {
		ByteArrayInputStream bis = new ByteArrayInputStream(
				"Hello World!".getBytes());
		Resource resource = new InputStreamResource(bis);
		if (resource.exists()) {
			dumpStream(resource);
		}
		/**
		 * InputStreamResource代表java.io.InputStream字节流，对于"getInputStream
		 * "操作将直接返回该字节流，因此只能读取一次该字节流，即"isOpen"永远返回true。
		 */
		Assert.assertEquals(true, resource.isOpen());
	}

	@Test
	public void testFileResource() {
		Resource resource = new FileSystemResource(new File("d:/test.txt"));
		if (resource.exists()) {
			dumpStream(resource);
		}
		/**
		 * FileSystemResource代表java.io.File资源，对于"getInputStream
		 * "操作将返回底层文件的字节流，"isOpen"将永远返回false，从而表示可多次读取底层文件的字节流。
		 */
		Assert.assertEquals(false, resource.isOpen());
	}

	@Test
	public void testClasspathResourceByDefaultClassLoader() throws IOException {
		Resource resource = new ClassPathResource(
				"com/sam/spring/chapter3/test1.properties");
		if (resource.exists()) {
			dumpStream(resource);
		}
		System.out.println("path:" + resource.getFile().getAbsolutePath());
		Assert.assertEquals(false, resource.isOpen());
	}

	/**
	 * 加载指定的ClassLoader类路径上相对于根路径的资源
	 */
	@Test
	public void testClasspathResourceByClassLoader() throws IOException {
		ClassLoader cl = this.getClass().getClassLoader();
		Resource resource = new ClassPathResource(
				"com/sam/spring/chapter3/test1.properties", cl);
		if (resource.exists()) {
			dumpStream(resource);
		}
		System.out.println("path:" + resource.getFile().getAbsolutePath());
		Assert.assertEquals(false, resource.isOpen());
	}

	/**
	 * 将尝试加载相对于当前类的路径的资源
	 */
	@Test
	public void testClasspathResourceByClass() throws IOException {
		/**
		 * "resource1"将加载com/sam/spring/chapter3/com/sam/spring/chapter3/
		 * test1.properties资源；"resource2”将加载"com/sam/spring/chapter3/test1.
		 * properties”；
		 */
		Class clazz = this.getClass();
		Resource resource1 = new ClassPathResource(
				"com/sam/spring/chapter3/test1.properties", clazz);
		if (resource1.exists()) {
			dumpStream(resource1);
		}
		System.out.println("path:" + resource1.getFile().getAbsolutePath());
		Assert.assertEquals(false, resource1.isOpen());

		Resource resource2 = new ClassPathResource("test1.properties",
				this.getClass());
		if (resource2.exists()) {
			dumpStream(resource2);
		}
		System.out.println("path:" + resource2.getFile().getAbsolutePath());
		Assert.assertEquals(false, resource2.isOpen());
	}

	/**
	 * 加载jar包里的资源，首先在当前类路径下找不到，最后才到Jar包里找，而且在第一个Jar包里找到的将被返回
	 */
	@Test
	public void classpathResourceTestFromJar() throws IOException {
		Resource resource = new ClassPathResource("overview.html");
		if (resource.exists()) {
			dumpStream(resource);
		}
		/**
		 * 不能使用"resource.getFile()"，应该使用"resource.getURL()"，
		 * 因为资源不存在于文件系统而是存在于jar包里，URL类似于"file:/C:/.../***.jar!/overview.html"
		 */
		System.out.println("path:" + resource.getURL().getPath());
		Assert.assertEquals(false, resource.isOpen());
	}

	private void dumpStream(Resource resource) {
		InputStream is = null;
		try {
			// 1.获取文件资源
			is = resource.getInputStream();
			// 2.读取资源
			byte[] descBytes = new byte[is.available()];
			is.read(descBytes);
			System.out.println(new String(descBytes));
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				// 3.关闭资源
				is.close();
			} catch (IOException e) {
			}
		}
	}
}
